<?php
namespace app\components\oauth2\repositories;

use app\helpers\Redis;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;

use app\components\oauth2\entities\AccessTokenEntity;

class AccessTokenRepository implements AccessTokenRepositoryInterface
{
    const PREFIX = 'access_token:';
    /**
     * {@inheritdoc}
     */
    public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity)
    {
        $redis = Redis::getRedis();
        $tokenId = $accessTokenEntity->getIdentifier();
        $expiryDateTime = $accessTokenEntity->getExpiryDateTime()->getTimestamp();
        $seconds = $expiryDateTime - \time();
        $redis->set(self::PREFIX.$tokenId,(string)$accessTokenEntity,['EX'=>$seconds]);
    }

    /**
     * {@inheritdoc}
     */
    public function revokeAccessToken($tokenId)
    {
        $redis = Redis::getRedis();
        $redis->del(self::PREFIX.$tokenId);
        // Some logic here to revoke the access token
    }

    /**
     * {@inheritdoc}
     */
    public function isAccessTokenRevoked($tokenId)
    {
        $redis = Redis::getRedis();
        return !$redis->exists(self::PREFIX.$tokenId); // Access token hasn't been revoked
    }

    /**
     * {@inheritdoc}
     */
    public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null)
    {
        $accessToken = new AccessTokenEntity();
        $accessToken->setClient($clientEntity);
        foreach ($scopes as $scope) {
            $accessToken->addScope($scope);
        }
        $accessToken->setUserIdentifier($userIdentifier);

        return $accessToken;
    }
}
